package com.runshu.newsmartark.base;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.example.controllibrary.LockControl;
import com.rscja.utility.StringUtility;
import com.runshu.newsmartark.R;
import com.runshu.newsmartark.common.CMD;
import com.runshu.newsmartark.common.ConstantUrl;
import com.runshu.newsmartark.entity.HwInfoUtils;
import com.runshu.newsmartark.entity.MqttBean;
import com.runshu.newsmartark.event.Event;
import com.runshu.newsmartark.event.EventBusUtils;
import com.runshu.newsmartark.event.EventCode;
import com.runshu.newsmartark.smartbox.SmartBoxHelper;
import com.runshu.newsmartark.smartbox.SmartBoxListener;
import com.runshu.newsmartark.smartbox.TarGet;
import com.runshu.newsmartark.util.SoundPoolUtils;
import com.runshu.newsmartark.util.common.SharedPreferencesUtils;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Timer;

import cn.com.example.rfid.driver.Driver;
import cn.com.example.rfid.driver.RfidDriver;

import static java.lang.Thread.sleep;

public abstract class BoxBaseActivity extends BaseActivity {
    private LocalBroadcastManager lbm;
    public static List<SmartBoxListener> listeners = new ArrayList<>();
    public static BoxBaseActivity ctx;
    Handler handler;
    Handler stopHandler;
    int iIndex = 0;
    long curDate, lastData;

    long startADate, startBDate;
    long lastADate, lastBDate;
    int Ct = 0;
    int flag = 0;
    public static String mStopTime = "10";
    public static boolean isStopTime = false;
    private int g_CloseDoorFlag = 0x0010;   // 默认电插锁0x0000，关门后GPIO5检测高电平  0x0010 电吸锁
    Timer soundTimer = new Timer();
    private ArrayList<HashMap<String, String>> tagList = new ArrayList<HashMap<String, String>>();
    private Map<String, HashMap<String, String>> tagresult = new HashMap<>();

    HashMap<String, String> hmap = new HashMap<>();
    HashMap<String, Integer> map = new HashMap<String, Integer>(100000);
    Driver driver;
    private boolean loopFlag = false;
    private static LocalBroadcastManager mLocalBroadcastManager = null;


    private LockControl.electrolStatusCallback statusCallback = new LockControl.electrolStatusCallback() {
        @Override
        public void onResult(boolean res) {
            if(res){
                sendBroadMessage(CMD.CloseDoorBroadcast);
                Log.e("Callback", "关门了");
                SoundPoolUtils.play(context, R.raw.raw_close, 0);
            }
        }
    };

    public void addBoxListener(SmartBoxListener listener) {
        Log.e("box", "addboxlistener");
        listeners.add(listener);
    }

    public void unRegisterBoxListener(SmartBoxListener listener) {
        Log.e("box", "unregisterboxlistener");
        listeners.remove(listener);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ctx = this;
        mLocalBroadcastManager = LocalBroadcastManager.getInstance(ctx);
        lbm = LocalBroadcastManager.getInstance(this);

        IntentFilter itent = new IntentFilter();
        itent.addAction(CMD.CloseDoorBroadcast);
        itent.addAction(CMD.OpenDoorBroadcast);
        itent.addAction(CMD.InventoryBroadcast);
        lbm.registerReceiver(receiver, itent);
        driver = new RfidDriver();

        handler = new Handler() {

            @Override
            public void handleMessage(Message msg) {
                addEPCToList(msg.obj + "", hmap, tagList);
                long nowTime = System.currentTimeMillis();
                long timedate = nowTime - lastData;
                Ct++;
            }
        };


        stopHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                if (msg.obj == "start") {

                    if (TarGet.getCurrentTarget() == 0) {
                        lastADate = System.currentTimeMillis() - startADate;
                        //todo targetresult 添加targetlist
                        for (HashMap<String, String> tmp : tagList) {
                            tagresult.put(tmp.get("epc"), tmp);
                        }
                        TarGet.setCurrentTarget(1);
                        Log.e("box_ab_scan==", "A面数据==" + tagList.size() + "res:" + tagresult.keySet().size());
                        SmartBoxHelper.getInstance().startScanA(context, 0);

                    } else {
                        //停止
                        for (HashMap<String, String> tmp : tagList) {
                            tagresult.put(tmp.get("epc"), tmp);
                        }
                        onScanResult(new ArrayList<>(tagresult.values()), lastADate, lastBDate);
                        Log.e("box_ab_scan==", "最后数据==" + tagList.size() + "res:" + tagresult.keySet().size());
                        Log.d("action", "停止");
                        tagList.clear();
                        TarGet.setCurrentTarget(0);
                    }

                }
            }
        };

        try {
            LockControl.OpenSerialPort("/dev/ttyACM0", 9600, statusCallback);

        }catch (Exception e){
            Log.e(TAG, Objects.requireNonNull(e.getMessage()));
        }
    }

    public boolean isCloseDoor() {
        int result = driver.GetGPIOStatus(0x10);
        // 门处于打开状态
        return (result & 0x0010) != 0x0010;

    }

    public void onScanResult(List<HashMap<String, String>> data, long a, long b) {
        Log.w("operatebox---", "scan");
        SmartBoxHelper.getInstance().stopScan(this);
        if (listeners != null) {
            for (SmartBoxListener smartBoxListener : listeners) {
                smartBoxListener.onScanResult(data, isCloseDoor(), a, b);
            }
        }
    }


    private void onOpenDoor() {
        Log.w("operatebox---", "opendoor");
        if (listeners != null) {
//            isCloseDoor = true;
            for (SmartBoxListener smartBoxListener : listeners) {
                smartBoxListener.onOpenDoor();
            }
        }
    }

    private void onCloseDoor() {


        Log.w("box", "app_oncloseDoor");
        SmartBoxHelper.getInstance().closeLigth(this, 0);
        Log.w("box", "app_listener" + listeners == null ? "null" : listeners.size() + "");

        if (listeners != null) {
            for (SmartBoxListener smartBoxListener : listeners) {
                smartBoxListener.onCloseDoor();
            }
        }
    }


    // sw = 1，开门；       sw = 0，关门
    public void SetDoorStatus(int sw) {
        if (sw == 1) {
            //先开吸锁，在开钩锁
            LockControl.electroLockCControl((byte) 0x11);

            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(50);
                        Log.e(TAG, "开电钩锁");
                        LockControl.electroLockGControl((byte) 0x11);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
//            new Handler().postDelayed(new Runnable() {
//                @Override
//                public void run() {
//
//                }
//            }, 50);
            Log.w("box", "app_onopeanDoor");

        } else {
            //关门
            LockControl.electroLockCControl((byte) 0x00);
            Log.w("box", "app_oncloseDoor");
        }

//        int mask = 0x0100;
//        int value = (int) (sw << 8);
//        int save = 0;
//        // 判断是否开启监听
//        if (loopFlag)
//        {
//            loopFlag    = false;
//            try {
//                sleep(200);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }
//        int result = driver.SetGPIOStatus(mask, value, save);
//        if (result == 1) {
//            if (sw == 0) {
//                // 如果是关门请求，设置成功后，则监听关门事件，监听到则上报
//                ListenDoorCloseEvent(1);
//            }else {
//                sendBroadMessage(CMD.OpenDoorBroadcast);
//            }
//
//            return true;
//        } else {
//            return false;
//        }
    }

    //  sw = 0，关门
    public void SetNotActionDoorStatus(int sw) {
        LockControl.electroLockCControl((byte) 0x00);
    }

    // sw = 1，开灯；       sw = 0，关灯
    public void SetLightStatus(int sw) {
        if (sw == 1) {
            LockControl.ledControl((byte) 0x11);
        } else {
            LockControl.ledControl((byte) 0x00);
        }
    }

    // 设置读写器发射功率
    public boolean SetReaderTxPower(int rPow, int wPow, int ant) {
        // antID 天线号，=0，表示
        int readPow, writePow, antID, saveFlag;

        readPow = rPow;             // readPow 读功率
        writePow = wPow;             // writePow 写功率
        antID = ant;              // antID 天线号，antID=0，表示设置所有天线的发射功率
        saveFlag = 1;                // 1 设置掉电保存，    0 设置掉电不保存，重启模块后，需重新设置
        int result = driver.SetTxPower(readPow, writePow, antID, saveFlag);
        if (result == 1) {
            return true;
        } else {
            return false;
        }
    }

    // 检测读写器端口和天线是否正常连接
    public String[] CheckReaderPortStatus() {
        String result = driver.Get_AntStatus();

        if ((result.equals("-1000")) || (result.equals("-1020"))) {
            return null;
        } else {
            String[] AntArrary = result.split(",");

            return AntArrary;
        }
    }

    // 设置读写器天线  antNum表示要设置的天线数量，
    // 举例, 设置天线1-天线8，共8个天线工作，则ant[] = {1, 2, 3, 4, 5, 6, 7, 8}, antNum = 8
    public boolean SetReaderAntenna(int[] ant, int antNum) {
        int saveFlag;

        saveFlag = 1;                // 1 设置掉电保存，    0 设置掉电不保存，重启模块后，需重新设置
        int result = driver.Set_Ant_More(ant, antNum, saveFlag);
        if (result == 1) {
            return true;
        } else {
            return false;
        }
    }
//    class GPIOThread extends Thread {
//
//        private int mBetween = 100;
//
//        public GPIOThread() {
//
//        }
//
//        public void run() {
//
//            while (loopFlag) {
//
//                try {
//                    int result = driver.GetGPIOStatus((byte) 0x10);
//                    if ((result & 0x0010) == g_CloseDoorFlag) {
//                        sendBroadMessage(CMD.CloseDoorBroadcast);
//                        loopFlag = false;
//                    }
//
//                    sleep(mBetween);
//
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//    }

    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.e("Receive", "Enter here");
            String action = intent.getAction();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                switch (Objects.requireNonNull(action)) {
                    case CMD.CloseDoorBroadcast:
//                        关灯
                        SetLightStatus(0);
                        new Handler().postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                startInventory();
                            }
                        }, 100);
//                        onCloseDoor();
                        EventBusUtils.sendEvent(new Event(EventCode.EventClose));
                        break;
                    default:
                        break;
                }
            }
        }
    };


    class TagThread extends Thread {

        private int mBetween = 0;

        public TagThread() {

        }

        public void run() {

            while (loopFlag) {

                if (isStopTime == true) {
                    curDate = System.currentTimeMillis();
                    long diff = curDate - lastData;

                    if ((mStopTime == null) || mStopTime.isEmpty()) {
                        mStopTime = "0";
                    }

                    int stopTime = Integer.parseInt(mStopTime);
                    if (diff > (stopTime)) {
//                        stopInventory();
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        flag = 0;

                        Message msg = stopHandler.obtainMessage();

                        msg.obj = "start";
                        stopHandler.sendMessage(msg);

                        break;
                    }
                }

                try {
                    String[] strEpc1 = {driver.GetBufData()};
                    String strEpc = strEpc1[0];
                    if (!StringUtility.isEmpty(strEpc)) {

                        if (strEpc.equals("Finish")) {

//                            // 盘点完成自动结束
//                            driver.stopRead();

                            flag = 0;
                            Message msg = stopHandler.obtainMessage();
                            msg.obj = "start";
                            stopHandler.sendMessage(msg);

                            break;
                        }

                        Message msg = handler.obtainMessage();

                        msg.obj = strEpc;
                        handler.sendMessage(msg);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                try {
                    sleep(mBetween);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }
    }

    public static int hexStringToAlgorism(String hex) {
        hex = hex.toUpperCase();
        int max = hex.length();
        int result = 0;
        for (int i = max; i > 0; i--) {
            char c = hex.charAt(i - 1);
            int algorism = 0;
            if (c >= '0' && c <= '9') {
                algorism = c - '0';
            } else {
                algorism = c - 55;
            }
            result += Math.pow(16, max - i) * algorism;
        }
        return result;
    }

    private void addEPCToList(String epc, HashMap<String, String> hmap, ArrayList<HashMap<String, String>> tagList) {

        int Hb = 0;
        int Lb = 0;
        int rssi = 0;
        String[] tmp = new String[3];
        HashMap<String, String> temp = new HashMap<>();
        String text = epc.substring(4);
        String len = epc.substring(0, 2);
        int epclen = (Integer.parseInt(len, 16) / 8) * 4;
        tmp[0] = text.substring(epclen, text.length() - 6);
        tmp[1] = text.substring(0, text.length() - 6);
        tmp[2] = text.substring(text.length() - 6, text.length() - 2);

        if (4 != tmp[2].length()) {
            tmp[2] = "0000";
        } else {
            Hb = Integer.parseInt(tmp[2].substring(0, 2), 16);
            Lb = Integer.parseInt(tmp[2].substring(2, 4), 16);
            rssi = ((Hb - 256 + 1) * 256 + (Lb - 256)) / 10;
        }

        int count = 0;

        if (tmp[1].length() <= 30) {
            temp.put("epc", tmp[1]);


            if (hmap.containsKey(tmp[1])) {
                String strTemp = hmap.get(tmp[1]);
                if (null != strTemp) {
                    int sn = Integer.valueOf(strTemp.split(",")[1]);
                    count = Integer.valueOf(strTemp.split(",")[0]) + 1;
                    temp.put("sn", "" + sn);
                    temp.put("count", "" + count);
                    temp.put("rssi", "" + rssi);
                    hmap.put(tmp[1], String.valueOf(count) + "," + String.valueOf(sn) + "," + rssi);
                    tagList.set(sn, temp);
                }
            } else {
                hmap.put(tmp[1], "1," + iIndex + "," + rssi);
                temp.put("sn", "" + iIndex);
                temp.put("count", "1");
                temp.put("rssi", "" + rssi);
                tagList.add(temp);
                //mListView.setAdapter(adapter);
                iIndex++;
            }
        }
    }

//    /**
//     * 停止识别
//     */
//    public void stopInventory() {
//
//        if (loopFlag) {
//
//            loopFlag = false;
//
//            driver.stopRead();
//
//        }
//
//    }

    /**
     * 开始识别
     */
    public void startInventory() {
        switch (flag) {
            case 0:
                tagList.clear();
                map.clear();
                hmap.clear();
                iIndex = 0;
                Ct = 0;
                // 设置Session和Target
                int session = 2;
                int times;
//                if (TarGet.getCurrentTarget() == 0) {
//                     times = (int) SharedPreferencesUtils.get( MyApplication.getApplication(), ConstantUrl.Share_CycleANum, 4 );
//                    startADate = System.currentTimeMillis();
//                    sendBroadMessage(CMD.InventoryBroadcast);
//                    Log.e("box_ab_scan", "开始盘点A ;A循环次数："+times);
//                } else {
//                    tagresult.clear();
//                    times = (int) SharedPreferencesUtils.get( MyApplication.getApplication(), ConstantUrl.Share_CycleBNum, 1 );
//                    startBDate = System.currentTimeMillis();
//                    Log.e("box_ab_scan", "开始盘点B ; B循环次数："+times);
//                }
                if (TarGet.getCurrentTarget() == 0) {
                    tagresult.clear();
                    times = (int) SharedPreferencesUtils.get(MyApplication.getApplication(), ConstantUrl.Share_CycleANum, 6);
                    startADate = System.currentTimeMillis();
                    Log.e("box_ab_scan", "开始盘点A ;A循环次数：" + times);
                } else {
                    times = (int) SharedPreferencesUtils.get(MyApplication.getApplication(), ConstantUrl.Share_CycleBNum, 6);
                    startBDate = System.currentTimeMillis();
                    sendBroadMessage(CMD.InventoryBroadcast);
                    Log.e("box_ab_scan", "开始盘点B ; B循环次数：" + times);
                }
                int target = TarGet.getCurrentTarget();
                SetReaderSession(session, target);
                driver.readMore(times);
                loopFlag = true;
                new TagThread().start();
                lastData = System.currentTimeMillis();

                if (soundTimer == null) {
                    soundTimer = new Timer();
                }
                flag = 1;
                break;
            case 1:
                iIndex = 0;
//                stopInventory();
//                try {
//                    Thread.sleep(5);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
                flag = 0;
                break;
            default:
                break;
        }


    }

    // 设置Session和 A/B     {A: target = 0}  {B: target = 1}
    public boolean SetReaderSession(int session, int target) {
        Log.e("box_setting", session + ":s|t:" + target);
        int[] gen2 = new int[10];

        // 先获取，才能设置
        String val = driver.GetGen2Para();

        if ((val.equals("-1000")) || (val.equals("-1020"))) {
            return false;
        }

        for (int i = 0; i < 8; i++) {
            // 获取参数
            gen2[i] = Integer.parseInt(val.substring(2 * i, 2 * (i + 1)), 16);
        }

        // 修改session
        gen2[3] = gen2[3] & 0xCF;
        int pos = session;
        gen2[3] = gen2[3] + (pos << 4);

        // 修改Target
        gen2[3] = gen2[3] & 0xF7;
        pos = target;
        gen2[3] = gen2[3] + (pos << 3);

        int status = 0;
        status = driver.SetGen2Para(0, gen2);            // 不掉电保存参数
        if (1 == status) {
            return true;
        } else {
            return false;
        }
    }

    //  发送广播
    public void sendBroadMessage(String msg) {
        Intent intent = new Intent();
        intent.setAction(msg);
        mLocalBroadcastManager.sendBroadcast(intent);
    }

//    //event
//    @Subscribe(threadMode = ThreadMode.MAIN)
//    public void onCloseEvent(Event event) {
//        if (event.getCode() == EventCode.EventClose) {
//            sendBroadMessage(CMD.CloseDoorBroadcast);
//        }
//    }
}
